/* Copyright (c) 2024 Qualcomm Technologies International, Ltd. */
/* %%version */

#include "csr_synergy.h"
#ifndef EXCLUDE_GATT_OTS_CLIENT_MODULE
#include "mcp.h"
#include "mcp_debug.h"
#include "mcp_common.h"
#include "gatt_service_discovery_lib.h"
#include "mcp_optional_service_init.h"

/***************************************************************************/
static void mcpOtsServiceInit(MCP *mcpInst, McpOptionalServices *optServicesLocal)
{
    if ((*optServicesLocal & MCP_OPTIONAL_SERVICE_OTS) == MCP_OPTIONAL_SERVICE_OTS)
    {
        if (mcpInst->otsData == NULL)
        {
            GattServiceDiscoverFindIncludedServiceStart(mcpInst->libTask,
                mcpInst->cid,
                GATT_SD_GMCS_SRVC);
        }
        else
        {
            uint8 i;
            for (i = 0; i < mcpInst->otsNum; i++)
            {
                GattOtscInitData init_data;

                init_data.cid = mcpInst->cid;
                init_data.startHandle = mcpInst->otsData[i].otsHandle->startHandle;
                init_data.endHandle = mcpInst->otsData[i].otsHandle->endHandle;

                GattOtscInitReq(mcpInst->libTask,
                    &init_data,
                    mcpInst->otsData[i].otsHandle);
            }
        }
        *optServicesLocal &= ~MCP_OPTIONAL_SERVICE_OTS;
    }
}

void mcpSendOptServInitCfm(MCP *mcpInst, McpOptionalServices optService, McpStatus status, ServiceHandle handle)
{
    McpInitOptServicesCfm *mcpOptMsg = CsrPmemAlloc(sizeof(*mcpOptMsg));

    mcpOptMsg->id = MCP_INIT_OPT_SERVICES_CFM;
    mcpOptMsg->prflHndl = mcpInst->mcpSrvcHndl;
    mcpOptMsg->optServiceInfoCount = mcpInst->optServiceCount;
    mcpOptMsg->status = status;

    if (mcpOptMsg->optServiceInfoCount)
    {
        mcpOptMsg->optSerInfo = (OptServiceInfo *)CsrPmemZalloc(sizeof(OptServiceInfo) * mcpOptMsg->optServiceInfoCount);

        if (mcpOptMsg->optSerInfo)
        {
            uint8 i;

            for (i = 0 ; i < mcpOptMsg->optServiceInfoCount; i++)
            {
                mcpOptMsg->optSerInfo[i].serviceHndl = handle;
                mcpOptMsg->optSerInfo[i].optService = optService << i;
            }
        }
    }

    McpMessageSend(mcpInst->appTask, mcpOptMsg);
}

bool McpSetOtsHandles(McpProfileHandle profileHandle, ServiceHandle mcsHandle, const McpOtsHandles *gattOtsData)
{
    MCP *mcpInst = FIND_MCP_INST_BY_PROFILE_HANDLE(profileHandle);

     /* Check the mcp istance and handle should be for GMCS(madatory as per MCP spec) as OTS is supported for GMCS as of now */
    if (mcpInst && mcsHandle == mcpInst->mcsSrvcHndl)
    {
       mcpInst->otsData = (McpOtsHandles*)CsrPmemZalloc(sizeof(McpOtsHandles));

       if (mcpInst->otsData)
       {
           memcpy(mcpInst->otsData, gattOtsData, sizeof(McpOtsHandles));
           return TRUE;
       }
    }
    return FALSE;
}

void McpInitOptServicesReq(McpProfileHandle profileHandle, McpOptionalServices optServices)
{
    MCP *mcpInst = FIND_MCP_INST_BY_PROFILE_HANDLE(profileHandle);
    McpOptionalServices optServicesLocal;

    if (mcpInst == NULL)
    {
         MCP_DEBUG("McpInitOptServicesReq mcpInst NUll profileHandle: %x\n", profileHandle);
         return;
    }

    /* Validate the optServices mask, if invalid return */
    if (optServices == MCP_OPTIONAL_SERVICE_INVALID)
    {
         McpInitOptServicesCfm* mcpOptMsg = CsrPmemAlloc(sizeof(*mcpOptMsg));

         mcpOptMsg->id = MCP_INIT_OPT_SERVICES_CFM;
         mcpOptMsg->prflHndl = mcpInst->mcpSrvcHndl;
         mcpOptMsg->optServiceInfoCount = 0;
         mcpOptMsg->optSerInfo = NULL;
         mcpOptMsg->status = MCP_STATUS_INVALID_PARAMETER;
         McpMessageSend(mcpInst->appTask, mcpOptMsg);
    }

    optServicesLocal = optServices;
    mcpInst->optServices = optServices;

    while (optServicesLocal)
    {
         mcpOtsServiceInit(mcpInst, &optServicesLocal);
        /* In future for other opt services add the handler */
    }
}
#endif /* EXCLUDE_GATT_OTS_CLIENT_MODULE */
